/*********************
* Author:Dzlua
* QQ:505544956
* time:2016/08/08
*/
#include "Button.h"
#include "../edui.h"

EDUI_NAMESPACE_BEGIN

Button* Button::GetInterface()
{
    Button* button = new Button;
#ifdef EDUI_TEST_NEW_DELETE
    ++m_newdeleteNum;
    Log("[Button] new button : %d", button);
#endif
#ifdef EDUI_USE_LUAPLUS
    LuaMgrPtr->Add("Button", button);
#endif
    return button;
}

void Button::Release()
{
#ifdef EDUI_TEST_NEW_DELETE
    --m_newdeleteNum;
    Log("[Button] delete button : %s, %d", this->GetName(), this);
#endif
#ifdef EDUI_USE_LUAPLUS
    LuaMgrPtr->Remove(this);
#endif
    delete this;
}

Button* Button::ToButton(Control* ctrl)
{
    return dynamic_cast<Button*>(ctrl);
}

Button::Button() : m_state(BUTTON_STATE_NORMAL)
{
    m_bDragWnd = false;
    m_bKeyboardEnabled = true;
    m_textColor.Reset(0, 0, 0, 255);
    m_hotTextColor.Reset(0, 0, 0, 255);
    m_pressedTextColor.Reset(0, 0, 0, 255);
    m_disabledTextColor.Reset(0, 0, 0, 255);

    m_ptPressedOffset.Reset(0, 0);
}

Button::~Button()
{}

bool Button::HandleMsg(Msg* msg)
{
    if (msg->msg == MSG_WND_LEAVE){
        if (m_state != BUTTON_STATE_NORMAL){
            m_state = BUTTON_STATE_NORMAL;
            this->Invaldate();
        }
    }

    if (msg->msg == MSG_MOUSE_MOVE){
        MouseMoveMsg *evt = &msg->motion;
        if (m_rc.IsInRect(evt->x, evt->y)){
            if (evt->state & MOUSE_BUTTON(MOUSE_BUTTON_LEFT)){
                if (m_state !=  BUTTON_STATE_PRESSED){
                    m_state =  BUTTON_STATE_PRESSED;
                    this->Invaldate();
                }
            } else {
                if (m_state !=  BUTTON_STATE_HOT){
                    m_state =  BUTTON_STATE_HOT;
                    this->Invaldate();
                }
            }
            return true;
        } else {
            if (m_state !=  BUTTON_STATE_NORMAL){
                m_state =  BUTTON_STATE_NORMAL;
                this->Invaldate();
            }
        }
    } else if (msg->msg == MSG_MOUSE_BUTTON_DOWN){
        MouseButtonMsg *evt = &msg->button;
        if (m_rc.IsInRect(evt->x, evt->y)){
            if (m_state !=  BUTTON_STATE_PRESSED){
                m_state =  BUTTON_STATE_PRESSED;
                this->Invaldate();
            }
            return true;
        }
    } else if (msg->msg == MSG_MOUSE_BUTTON_UP){
        MouseButtonMsg *evt = &msg->button;
        if (m_rc.IsInRect(evt->x, evt->y)){
            if (m_state !=  BUTTON_STATE_HOT){
                m_state =  BUTTON_STATE_HOT;
                this->Invaldate();
            }

            this->DoEvent(EVENT_CLICK);
            return true;
        } else {
            if (m_state !=  BUTTON_STATE_NORMAL){
                m_state =  BUTTON_STATE_NORMAL;
                this->Invaldate();
            }
        }
    }

    if (msg->msg == MSG_KEY_DOWN){
        KeyboardMsg* evt = &msg->key;
        if (evt->key == KEY_RETURN){
            this->DoEvent(EVENT_KEY_ENTER);
        }
    }
    return Control::HandleMsg(msg);
}

void Button::RenderStatusImages(IRender* render, const Rect* rc)
{
    if (!m_bEnabled){
        m_state = BUTTON_STATE_DISABLED;
    }

    if (m_state == BUTTON_STATE_NORMAL){
        this->DrawImage(render, &m_normalImage);
    } else if (m_state == BUTTON_STATE_HOT){
        this->DrawImage(render, &m_hotImage);
    } else if (m_state == BUTTON_STATE_PRESSED){
        this->DrawImage(render, &m_pressedImage);
    } else if (m_state == BUTTON_STATE_DISABLED){
        this->DrawImage(render, &m_disabledImage);
    }
}

void Button::RenderText(IRender* render, const Rect* renderrc)
{
    if (!m_bEnabled){
        m_state = BUTTON_STATE_DISABLED;
    }
    
    if (m_text.IsEmpty()) return;

    //get text
    const char* text = this->GetTranslateText();
    if (!text) return;

    //get font
    IFont* font = this->GetFont();
    if (!font) return;

    //render
    Size sz = font->GetSizeUTF8(text);
    Rect rc = this->GetTextAlignRect(&sz);

    switch (m_state){
    case BUTTON_STATE_NORMAL :
        render->DrawText(text, &rc, font, &m_textColor);
        break;
    case BUTTON_STATE_HOT :
        render->DrawText(text, &rc, font, &m_hotTextColor);
        break;
    case BUTTON_STATE_PRESSED :
        rc.x += m_ptPressedOffset.x;
        rc.y += m_ptPressedOffset.y;

        render->DrawText(text, &rc, font, &m_pressedTextColor);
        break;
    case BUTTON_STATE_DISABLED :
        render->DrawText(text, &rc, font, &m_disabledTextColor);
        break;
    }
}

void Button::SetPressedOffset(int x, int y)
{
    m_ptPressedOffset.x = x;
    m_ptPressedOffset.y = y;
}
    
Point Button::GetPressedOffset()
{
    return m_ptPressedOffset;
}

Color* Button::GetDestColor(const char* value)
{
    if (0 == strcmp(value, "hottext")){
        return &m_hotTextColor;
    } else if (0 == strcmp(value, "pressedtext")){
        return &m_pressedTextColor;
    } else if (0 == strcmp(value, "disabledtext")){
        return &m_disabledTextColor;
    }
    return Label::GetDestColor(value);
}

ImageData* Button::GetDestImageData(const char* value)
{
    if (0 == strcmp(value, "normal")){
        return &m_normalImage;
    } else if (0 == strcmp(value, "hot")){
        return &m_hotImage;
    } else if (0 == strcmp(value, "pressed")){
        return &m_pressedImage;
    } else if (0 == strcmp(value, "disabled")){
        return &m_disabledImage;
    }
    return Control::GetDestImageData(value);
}

void Button::SetAttribute(const char* name, const char* value)
{
    if (0 == strcmp(name, "pressedoffset")){
        Point pt = ParserPoint(value, 0, 0);
        this->SetPressedOffset(pt.x, pt.y);
    } else {
        Label::SetAttribute(name, value);
    }
}

void Button::DoEvent(EventType type, void* data1, void* data2)
{
    switch (type){
        case EVENT_CLICK :     this->evt.click.emit(this); break;
        case EVENT_KEY_ENTER : this->evt.click.emit(this); break;
    }
#ifdef EDUI_USE_LUAPLUS
    switch (type){
        case EVENT_CLICK :     LuaMgrPtr->DoEvent(this, "click"); break;
        case EVENT_KEY_ENTER : LuaMgrPtr->DoEvent(this, "click"); break;
    }
#endif
}

void Button::OnMouseOut()
{
    Label::OnMouseOut();
    m_state = BUTTON_STATE_NORMAL;
    if (!m_bEnabled){
        m_state = BUTTON_STATE_DISABLED;
    }
    this->Invaldate();
}

EDUI_NAMESPACE_END
